﻿package code {
	// class creates a snowflake
	
	import flash.display.Sprite;
	import flash.geom.*;
	import fl.motion.Color;
	
	public class Snowflake extends Sprite{
		public var vertices:Array;
		private var flakeColor, scale, maxLength:Number;
		public var flakeSpeed:Number;
		
		public function Snowflake(xVal:Number, yVal:Number, size:Number, rot:Number, color:Number, mxLength:Number, spd:Number) {
			x = xVal;	// x position
			y = yVal;	// y position
			scale = size;	// size to scale it by
			rotation = rot; // amount to rotate the snowflakes
			flakeColor = color;	// color of the flakes
			maxLength = mxLength;	// max times to iterate (determined by number of vertices)
			vertices = new Array();	// holds the vertices
			flakeSpeed = spd;		// speed the snowflake falls at
		}
		
		// method recurisvely creates snowflakes
		// startFlake is the previous snowflake being passed in
		// arrayFlakes are all the snowflakes so far. 
		// it is noted that arrayFlakes seems ineffcient, however it is how we get arou
		public function create():Snowflake{
			var distance:Number;	// distance from each point to each other
			var currentVerts, vertsUsing, newVerts:Array;	//  arrays for keeping track of vertices
			
			vertsUsing = new Array(); // instantiates the arrays
			newVerts = new Array();
			
			for each(var v:Vertex in vertices){		// pushes the initial veritces
				vertsUsing.push(v);
			}
			
			if(vertices.length > 0)					// in case it is null
				vertsUsing.push(vertices[0]);
				
			if(vertices.length < maxLength){	// base case: max times to recurse
				for(var i:int = 0; i < vertsUsing.length - 1; i++){		// checks it at the length of the array - 1 so that it is not trying to get a vertex that does not exist
					currentVerts = vertsUsing;	// refrence to make more clear
					newVerts.push(currentVerts[i]);	// pushes the current vertex we are using
					
					distance = Math.sqrt(Math.pow(vertsUsing[i + 1].x - vertsUsing[i].x, 2) + Math.pow(vertsUsing[i + 1].y - vertsUsing[i].y, 2));	// does the distance formula between current point and next point
					
					var thirdDist = distance / 3;	// gets a third of the distance on there
					
					var thirdDistX:Number = currentVerts[i].x + (1/3)*(currentVerts[i + 1].x - currentVerts[i].x); // finds the point a 1/3 down the line
					var thirdDistY:Number = currentVerts[i].y + (1/3)*(currentVerts[i + 1].y - currentVerts[i].y); // uses forumula y = y1 + r(y2 - y1)
					var startVert = new Vertex(thirdDistX, thirdDistY);
										
					var thirdDistX2:Number = currentVerts[i].x + (2/3)*(currentVerts[i + 1].x - currentVerts[i].x);	// finds the point 2/3 down the line
					var thirdDistY2:Number = currentVerts[i].y + (2/3)*(currentVerts[i + 1].y - currentVerts[i].y);
					var endVert = new Vertex(thirdDistX2, thirdDistY2);
										
					newVerts.push(startVert);	// adds the new vertex to the vertices list

					var currentTheta:Number = Math.atan2(thirdDistY2 - thirdDistY, thirdDistX2 - thirdDistX);   // finds the current angle that the points are at
					var theta:Number = (2*Math.PI) - (Math.PI / 3);  // makes it so that the inverse angle is gotten through 2PI - the angle wanted to make
					
					theta += currentTheta;	// adds the wanted angle to the current angle

					var middleVert:Vertex = new Vertex(thirdDist * Math.cos(theta) + startVert.x, thirdDist * Math.sin(theta) + startVert.y);	// uses r*cos(theta) + prevX to find the point of the triangle
					newVerts.push(middleVert);	// pushes the middle vertex
					newVerts.push(endVert);		// pushes the end vertex
				}
				
				vertices = new Array(); // clears the current vertices so that they do not copy over
				
				for each(var vx:Vertex in newVerts){
					vertices.push(vx);  // populates vertex with newly created ones
				}

				create();  // this does recursion :D
			}
			return this; // returns the final snowflake
		}
		
		// draws the snowflakes, derived from drawing the polygons
		public function drawFlake(){
			if(vertices[0] != null){	// if the snowflakes is not null it drwas it
				graphics.beginFill(flakeColor,0);
				graphics.lineStyle(1,flakeColor);
				graphics.moveTo(vertices[0].x * scale, vertices[0].y * scale);
				
				for each(var v:Vertex in vertices){
					graphics.lineTo(v.x * scale, v.y * scale);
				}
				
				graphics.endFill();
			}
		}

	}
	
}
